# Copyright (c) 2024-2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'erb'
require_relative 'common_gen_tests_api'

abckit_scripts = File.dirname(__FILE__)
abckit_root = File.expand_path("../", abckit_scripts)
abckit_test = File.join(abckit_root, "/tests/wrong_ctx_tests/")

excluded_funcs = [
    "getLastError",
]


funcs_without_two_abckit_entites = [
  "destroyGraph",
  "closeFile",
  "openAbc",
  "writeAbc",
  "fileGetVersion",
  "fileEnumerateModules",
  "fileEnumerateExternalModules",
  "moduleGetFile",
  "moduleGetName",
  "moduleIsExternal",
  "moduleEnumerateImports",
  "moduleEnumerateExports",
  "moduleEnumerateClasses",
  "moduleEnumerateTopLevelFunctions",
  "importDescriptorGetFile",
  "importDescriptorGetImportedModule",
  "importDescriptorGetImportingModule",
  "importDescriptorGetName",
  "importDescriptorGetAlias",
  "exportDescriptorGetFile",
  "exportDescriptorGetExportingModule",
  "exportDescriptorGetExportedModule",
  "exportDescriptorGetName",
  "exportDescriptorGetAlias",
  "classGetFile",
  "classGetModule",
  "classGetName",
  "classEnumerateMethods",
  "functionGetFile",
  "functionGetModule",
  "functionGetName",
  "functionGetParentFunction",
  "functionGetParentClass",
  "functionEnumerateAnnotations",
  "functionIsStatic",
  "functionIsNative",
  "functionIsCtor",
  "functionIsAnonymous",
  "annotationGetFile",
  "annotationEnumerateElements",
  "typeGetTypeId",
  "typeGetReferenceClass",
  "literalArrayEnumerateElements",
  "arrayValueGetLiteralArray",
  "literalGetBool",
  "literalGetDouble",
  "literalGetFloat",
  "literalGetString",
  "literalGetMethodAffiliate",
  "literalGetTag",
  "literalGetU16",
  "literalGetMethodAffiliate",
  "literalGetU32",
  "literalGetU64",
  "literalGetU8",
  "valueGetDouble",
  "valueGetString",
  "valueGetType",
  "valueGetU1",
  "createLiteralArrayValue",
  "createLiteralArrayValue",
  "createLiteralBool",
  "createLiteralDouble",
  "createLiteralFloat",
  "createLiteralString",
  "createLiteralMethodAffiliate",
  "createLiteralU16",
  "createLiteralMethodAffiliate",
  "createLiteralU32",
  "createLiteralU64",
  "createLiteralU8",
  "createReferenceType",
  "createString",
  "iCreateTypeof",
  "createValueDouble",
  "createValueString",
  "createValueU1",
  "moduleRemoveExport",
  "moduleRemoveImport",
  "iSetConditionCode",
  "iSetExportDescriptor",
  "iSetInput",
  "iSetInputs",
  "iSetLiteralArray",
  "iSetModule",
  "iSetTargetType",
  "iVisitInputs",
  "iVisitUsers",
  "iSetImportDescriptor",
  "bbRemoveAllInsts",
  "bbCreateEmpty",
  "bbDump",
  "bbGetFalseBranch",
  "bbGetTrueBranch",
  "bbGetFirstInst",
  "bbGetGraph",
  "bbGetId",
  "bbGetImmediateDominator",
  "bbGetLastInst",
  "bbGetNumberOfInstructions",
  "bbGetPredBlockCount",
  "bbGetPredBlockCount",
  "bbGetSuccBlockCount",
  "bbGetSuccBlockCount",
  "bbGetTrueBranch",
  "bbIsCatchBegin",
  "bbIsCatchBegin",
  "bbIsEnd",
  "bbIsLoopHead",
  "bbIsLoopPrehead",
  "bbIsStart",
  "bbIsTryBegin",
  "bbIsTryBegin",
  "bbIsTryEnd",
  "bbSplitBlockAfterInstruction",
  "bbVisitDominatedBlocks",
  "bbVisitPredBlocks",
  "bbVisitSuccBlocks",
  "bbCreatePhi",
  "gFindOrCreateConstantF64",
  "gFindOrCreateConstantI32",
  "gFindOrCreateConstantI64",
  "gFindOrCreateConstantU64",
  "gCreateNullPtr",
  "gDump",
  "gGetBasicBlock",
  "gGetEndBasicBlock",
  "gGetNumberOfBasicBlocks",
  "gGetParameter",
  "gGetNumberOfParameters",
  "gGetStartBasicBlock",
  "gRunPassRemoveUnreachableBlocks",
  "gVisitBlocksRpo",
  "iCheckIsCall",
  "iCreateAsyncfunctionenter",
  "iCreateCallruntimeCreateprivateproperty",
  "iCreateCallruntimeLdsendableclass",
  "iCreateCallruntimeLdsendableexternalmodulevar",
  "iCreateCallruntimeLdsendablevar",
  "iCreateCallruntimeNewsendableenv",
  "iCreateCallruntimeWideldsendableexternalmodulevar",
  "iCreateCallruntimeWideldsendablevar",
  "iCreateCallruntimeWidenewsendableenv",
  "iCreateCopyrestargs",
  "iCreateCreatearraywithbuffer",
  "iCreateCreateemptyarray",
  "iCreateCreateemptyobject",
  "iCreateCreateobjectwithbuffer",
  "iCreateDebugger",
  "iCreateGetunmappedargs",
  "iCreateLdbigint",
  "iCreateLdexternalmodulevar",
  "iCreateLdfalse",
  "iCreateLdfunction",
  "iCreateLdglobal",
  "iCreateLdglobalvar",
  "iCreateLdhole",
  "iCreateLdinfinity",
  "iCreateLdlexvar",
  "iCreateLdlocalmodulevar",
  "iCreateLdnan",
  "iCreateLdnewtarget",
  "iCreateLdnull",
  "iCreateLdsymbol",
  "iCreateLdthis",
  "iCreateLdthisbyname",
  "iCreateLdtrue",
  "iCreateLdundefined",
  "iCreateNewlexenv",
  "iCreateNewlexenvwithname",
  "iCreatePoplexenv",
  "iCreateReturnundefined",
  "iCreateThrowDeletesuperproperty",
  "iCreateThrowNotexists",
  "iCreateThrowPatternnoncoercible",
  "iCreateTryldglobalbyname",
  "iCreateWideCopyrestargs",
  "iCreateWideLdexternalmodulevar",
  "iCreateWideLdlexvar",
  "iCreateWideLdlocalmodulevar",
  "iCreateWideLdpatchvar",
  "iCreateWideNewlexenv",
  "iCreateWideNewlexenvwithname",
  "iCreateLoadString",
  "iCreateReturnVoid",
  "iDump",
  "iGetBasicBlock",
  "iGetConditionCode",
  "iGetConstantValueF64",
  "iGetConstantValueI64",
  "iGetConstantValueU64",
  "iGetExportDescriptor",
  "iGetId",
  "iGetImmediate",
  "iGetImmediateCount",
  "iGetImportDescriptor",
  "iGetInputCount",
  "iGetInputCount",
  "iGetLiteralArray",
  "iGetFunction",
  "iGetModule",
  "iGetNext",
  "iGetOpcode",
  "iGetPrev",
  "iGetTargetType",
  "iGetType",
  "iGetUserCount",
  "iRemove",
  "iSetImmediate",
  "iCreateLoadConstArray",
  "iCreateLoadNullValue",
  "iGetString",
  "iSetString"
]

funcs_without_helper = [
  "coreAnnotationElementToArkTsAnnotationElement",
  "coreNamespaceToArkTsNamespace",
  "annotationElementGetAnnotation",
  "moduleEnumerateAnonymousFunctions",
  "annotationInterfaceFieldGetName",
  "classEnumerateAnnotations",
  "functionEnumerateNestedFunctions",
  "functionEnumerateNestedClasses",
  "literalGetMethod",
  "namespaceGetName",
  "functionGetParentNamespace",
  "moduleEnumerateNamespaces",
  "annotationInterfaceGetFile",
  "annotationInterfaceGetName",
  "moduleEnumerateAnnotationInterfaces",
  "annotationElementGetFile",
  "namespaceGetParentNamespace",
  "coreFunctionToArkTsFunction",
  "coreAnnotationInterfaceFieldToArkTsAnnotationInterfaceField",
  "arkTsAnnotationInterfaceFieldToCoreAnnotationInterfaceField",
  "coreImportDescriptorToArkTsImportDescriptor",
  "arkTsImportDescriptorToCoreImportDescriptor",
  "coreClassToArkTsClass",
  "arkTsClassToCoreClass",
  "arkTsModuleToCoreModule",
  "coreAnnotationToArkTsAnnotation",
  "arkTsAnnotationElementToCoreAnnotationElement",
  "arkTsFunctionToCoreFunction",
  "arkTsExportDescriptorToCoreExportDescriptor",
  "arkTsAnnotationToCoreAnnotation",
  "arkTsV1NamespaceGetConstructor",
  "arkTsNamespaceToCoreNamespace",
  "arkTsAnnotationInterfaceToCoreAnnotationInterface",
  "coreExportDescriptorToArkTsExportDescriptor",
  "coreModuleToArkTsModule",
  "coreAnnotationInterfaceToArkTsAnnotationInterface",
  "annotationInterfaceRemoveField",
  "annotationRemoveAnnotationElement",
  "classRemoveAnnotation",
  "functionAddAnnotation",
  "functionRemoveAnnotation",
  "annotationAddAnnotationElement",
  "moduleAddImportFromArkTsV1ToArkTsV1",
  "classAddAnnotation",
  "moduleAddExportFromArkTsV2ToArkTsV2",
  "moduleAddImportFromArkTsV2ToArkTsV2",
  "moduleAddAnnotationInterface",
  "fileAddExternalModuleArktsV1",
  "annotationInterfaceAddField",
  "moduleAddExportFromArkTsV1ToArkTsV1",
  "bbGetPredBlock",
  "bbGetSuccBlock",
  "gInsertTryCatch",
  "iGetConstantValueI32",
  "bbDisconnectSuccBlock",
  "bbIsTry",
  "gGetIsa",
  "bbIsCatch",
  "iGetInput",
  "gGetFile",
  "annotationInterfaceFieldGetFile",
  "annotationInterfaceFieldGetDefaultValue",
  "literalGetLiteralArray",
  "annotationInterfaceGetModule",
  "namespaceEnumerateTopLevelFunctions",
  "annotationInterfaceFieldGetInterface",
  "literalGetFile",
  "annotationElementGetValue",
  "classGetParentFunction",
  "classGetParentNamespace",
  "annotationGetInterface",
  "annotationInterfaceFieldGetType",
  "annotationInterfaceEnumerateFields",
  "moduleGetTarget",
  "namespaceEnumerateNamespaces",
  "annotationElementGetName",
  "createGraphFromFunction",
  "namespaceEnumerateClasses",
  "valueGetFile",
  "abckitStringToString",
  "bbCreateCatchPhi",
  "iGetClass",
  "iSetClass",
  "jsImportDescriptorToCoreImportDescriptor",
  "jsFunctionToCoreFunction",
  "jsClassToCoreClass",
  "coreClassToJsClass",
  "jsExportDescriptorToCoreExportDescriptor",
  "coreImportDescriptorToJsImportDescriptor",
  "coreModuleToJsModule",
  "coreFunctionToJsFunction",
  "coreExportDescriptorToJsExportDescriptor",
  "jsModuleToCoreModule",
  "fileAddExternalModule",
  "moduleAddExportFromJsToJs",
  "moduleAddImportFromJsToJs",
  "createLiteralMethod",
  "createLiteralLiteralArray",
  "createLiteralArray",
  "createType",
]

funcs_varargs = [
  "iCreateNewobjrange",
  "iCreateWideSupercallthisrange",
  "iCreateSupercallthisrange",
  "iCreateWideNewobjrange",
]

excluded_funcs += funcs_without_two_abckit_entites
excluded_funcs += funcs_varargs
excluded_funcs += funcs_without_helper

implemented_api_map = collect_implemented_api_map(excluded_funcs)
wrong_ctx_tests_erb = File.join(abckit_test, "wrong_ctx_tests.cpp.erb")
implemented_api_map.each_key do |domain|
  iteration = 0
  index = 0
  slice_size = 100
  api_funcs_arr = implemented_api_map[domain]
  total_domain_api_funcs = api_funcs_arr.length

  puts "#{domain}: #{total_domain_api_funcs}"

  while index < total_domain_api_funcs do
    testfile_fullpath = File.join(abckit_test, "wrong_ctx_tests_#{domain}_#{iteration}.cpp")
    res = ERB.new(File.read(wrong_ctx_tests_erb), nil, "%").result(binding)
    File.write(testfile_fullpath, res)
    iteration += 1
    index += slice_size
  end
end